﻿using LanguagePolish.Base;
using LanguagePolish.EntityModel;
using LanguagePolish.Models;
using LanguagePolish.Views;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using System.Windows.Threading;

namespace LanguagePolish.ViewModels
{
    class ClassesViewModel : BaseViewModel
    {
        private ClassesModel model;
        
        private DispatcherTimer timer;

        private string searchPattern;
        public string SearchPattern
        {
            get { return searchPattern; }
            set 
            { 
                searchPattern = value;
                UpdateTeacherCollectionWithWaiting();
                OnPropertyChanged("SearchPattern");
            }
        }

        private ObservableCollection<Class> classes;

        public ObservableCollection<Class> Classes { get { return classes; } }

        public ICommand AddClassCommand { get; private set; }
        public ICommand EditClassCommand { get; private set; }
        public ICommand RemoveClassCommand { get; private set; }
        public ICommand ShowInfoCommand { get; private set; }

        public ClassesViewModel()
        {
            model = new ClassesModel();
            AddClassCommand = new RelayCommand(AddNewClass, (o) => model.CanUserAddClasses);
            EditClassCommand = new RelayCommand((o) => EditClass((Class)o), (o) => model.CanUserEditClasses);
            RemoveClassCommand = new RelayCommand((o) => RemoveClass((Class)o), (o) => model.CanUserRemoveClasses);
            ShowInfoCommand = new RelayCommand((o) => ShowClassInfo((Class)o));
            
            timer = new DispatcherTimer();
            timer.Interval = new TimeSpan(0, 0, 0, 0, 300);
            timer.Tick += timer_RefreshFilter;

            UpdateClassCollection();
        }

        private void UpdateTeacherCollectionWithWaiting()
        {
            timer.Stop();
            timer.Start();
        }

        private void UpdateClassCollection()
        {
            var res = model.GetClassesWithFilter(searchPattern);
            classes = new ObservableCollection<Class>(res);
            OnPropertyChanged("Classes");
            timer.Stop();
        }

        void timer_RefreshFilter(object sender, EventArgs e)
        {
            UpdateClassCollection();
        }

        private void AddNewClass()
        {
            Class myClass = new Class();
            AddClassView addClassDialog = new AddClassView(myClass);
            bool? res = addClassDialog.ShowDialog();
            if (res == true)
            {
                classes.Add(myClass);      // добавляем нового тичера без обновления свойства.
                model.AddClass(myClass);
                LinksProvider.Model.CollectionsHasBeenChanged();
            }
        }

        private void EditClass(Class myClass)
        {
            AddClassView addClassDialog = new AddClassView(myClass, true);
            bool? res = addClassDialog.ShowDialog();
            if (res == true)
            {
                myClass.NotifyAll();    // обновляем все свойства
                model.SaveChanges();
                LinksProvider.Model.CollectionsHasBeenChanged();
            }
            else
            {
                model.RollbackClass(myClass);     // откат изменений
            }
        }

        private void RemoveClass(Class myClass)
        {
            MessageBoxResult res = MessageBox.Show("Delete this class?", "Attention", MessageBoxButton.YesNo, MessageBoxImage.Question);
            if (res == MessageBoxResult.Yes)
            {
                model.DeleteClass(myClass);
                classes.Remove(myClass);       // из каждой коллекции удаляем отдельно
                LinksProvider.Model.CollectionsHasBeenChanged();
            }
        }

        private void ShowClassInfo(Class myClass)
        {
            ClassInfoView infoDialog = new ClassInfoView(myClass);
            infoDialog.ShowDialog();
        }
    }
}
